#include "cpu/exec/template-start.h"


// 0x39
make_helper(cmpaaa){
    //解析参数
    int len = decode_r2rm_l(eip + 1);
    //提取第一参数
    switch (op_src->type){
        case OP_TYPE_REG:
            switch (op_src->reg){
                case 0:
                    op_src->val = cpu.eax;
                    break;
                case 1:
                    op_src->val = cpu.ecx;
                    break;
                case 2:
                    op_src->val = cpu.edx;
                    break;
                case 3:
                    op_src->val = cpu.ebx;
                    break;
                case 4:
                    op_src->val = cpu.esp;
                    break;
                case 5:
                    op_src->val = cpu.ebp;
                    break;
                case 6:
                    op_src->val = cpu.esi;
                    break;
                case 7:
                    op_src->val = cpu.edi;
                    break;
                default:
                    assert(0);
            }
            break;
            case OP_TYPE_MEM:
                op_src->val = swaddr_read(op_src->addr, DATA_BYTE);
                break;
            default:
                assert(0);
    }
    //提取第二参数
    switch (op_dest->type){
        case OP_TYPE_REG:
            switch (op_dest->reg){
                case 0:
                    op_dest->val = cpu.eax;
                    break;
                case 1:
                    op_dest->val = cpu.ecx;
                    break;
                case 2:
                    op_dest->val = cpu.edx;
                    break;
                case 3:
                    op_dest->val = cpu.ebx;
                    break;
                case 4:
                    op_dest->val = cpu.esp;
                    break;
                case 5:
                    op_dest->val = cpu.ebp;
                    break;
                case 6:
                    op_dest->val = cpu.esi;
                    break;
                case 7:
                    op_dest->val = cpu.edi;
                    break;
                default:
                    assert(0);
            }
            break;
            case OP_TYPE_MEM:
                op_dest->val = swaddr_read(op_dest->addr, DATA_BYTE);
                break;
            default:
                assert(0);
    }
    //进行减法运算
    int result = op_dest->val - op_src->val;
    //更新标志寄存器
    cpu.eflags.CF = op_dest->val < op_src->val;
    cpu.eflags.ZF = result == 0;
    cpu.eflags.SF = result < 0;
    cpu.eflags.OF = (MSB(op_dest->val) != MSB(op_src->val)) && (MSB(op_dest->val) != MSB(result));
    //返回指令长度
    // Log("len = %d", len);
    return 1 + len;

}

make_helper(cmpaaa){
    //解析参数
    int len = decode_si2rm_l(eip + 1);
    //提取第一参数
    // Log("src->type = %d", op_src->type);
    // Log("dest->type = %d", op_dest->type);
    switch (op_src->type){
        //根据不同的参数类型，提取参数的值
        case OP_TYPE_REG:
            switch (op_src->reg){
                case 0:
                    op_src->val = cpu.eax;
                    break;
                case 1:
                    op_src->val = cpu.ecx;
                    break;
                case 2:
                    op_src->val = cpu.edx;
                    break;
                case 3:
                    op_src->val = cpu.ebx;
                    break;
                case 4:
                    op_src->val = cpu.esp;
                    break;
                case 5:
                    op_src->val = cpu.ebp;
                    break;
                case 6:
                    op_src->val = cpu.esi;
                    break;
                case 7:
                    op_src->val = cpu.edi;
                    break;
                default:
                    assert(0);
            }
            break;
            case OP_TYPE_IMM:
                break;
            case OP_TYPE_MEM:
                op_src->val = swaddr_read(op_src->addr, DATA_BYTE);
                break;
            default:
                assert(0);
    }
    //提取第二参数
    switch (op_dest->type){
        case OP_TYPE_REG:
            switch (op_dest->reg){
                case 0:
                    op_dest->val = cpu.eax;
                    break;
                case 1:
                    op_dest->val = cpu.ecx;
                    break;
                case 2:
                    op_dest->val = cpu.edx;
                    break;
                case 3:
                    op_dest->val = cpu.ebx;
                    break;
                case 4:
                    op_dest->val = cpu.esp;
                    break;
                case 5:
                    op_dest->val = cpu.ebp;
                    break;
                case 6:
                    op_dest->val = cpu.esi;
                    break;
                case 7:
                    op_dest->val = cpu.edi;
                    break;
                default:
                    assert(0);
            }
            break;
            case OP_TYPE_MEM:
                op_dest->val = swaddr_read(op_dest->addr, DATA_BYTE);
                break;
            default:
                assert(0);
    }
    //进行减法运算
    int result = op_dest->val - op_src->val;
    //更新标志寄存器
    cpu.eflags.CF = op_dest->val < op_src->val;
    cpu.eflags.ZF = result == 0;
    cpu.eflags.SF = result < 0;
    cpu.eflags.OF = (MSB(op_dest->val) != MSB(op_src->val)) && (MSB(op_dest->val) != MSB(result));
    //返回指令长度

    return len + 1;
}


// 0x3c cmp
make_helper(cmpccc){
    //解析参数
    int len = decode_i2a_b(eip + 1);
    //提取第一参数
    switch (op_src->type){
        case OP_TYPE_IMM:
            break;
        default:
            assert(0);
    }
    //提取第二参数
    switch (op_dest->type){
        case OP_TYPE_REG:
            switch (op_dest->reg){
                case 0:
                    op_dest->val = cpu.eax;
                    break;
                case 1:
                    op_dest->val = cpu.ecx;
                    break;
                case 2:
                    op_dest->val = cpu.edx;
                    break;
                case 3:
                    op_dest->val = cpu.ebx;
                    break;
                case 4:
                    op_dest->val = cpu.esp;
                    break;
                case 5:
                    op_dest->val = cpu.ebp;
                    break;
                case 6:
                    op_dest->val = cpu.esi;
                    break;
                case 7:
                    op_dest->val = cpu.edi;
                    break;
                default:
                    assert(0);
            }
            break;
        case OP_TYPE_MEM:
            op_dest->val = swaddr_read(op_dest->addr, DATA_BYTE);
            break;
        default:
            assert(0);
    }
    //进行减法运算
    int result = op_dest->val - op_src->val;
    //更新标志寄存器
    cpu.eflags.CF = op_dest->val < op_src->val;
    cpu.eflags.ZF = result == 0;
    cpu.eflags.SF = result < 0;
    cpu.eflags.OF = (MSB(op_dest->val) != MSB(op_src->val)) && (MSB(op_dest->val) != MSB(result));
    //返回指令长度
    return len + 1;
    
}


// 0x80 cmpb
make_helper(cmpddd){
    //解析参数
    int len = decode_i2rm_b(eip + 1);
    //提取第一参数
    // Log("src->type = %d", op_src->type);
    // Log("dest->type = %d", op_dest->type);
    switch (op_src->type){
        //根据不同的参数类型，提取参数的值
        case OP_TYPE_REG:
            switch (op_src->reg){
                case 0:
                    op_src->val = cpu.eax;
                    break;
                case 1:
                    op_src->val = cpu.ecx;
                    break;
                case 2:
                    op_src->val = cpu.edx;
                    break;
                case 3:
                    op_src->val = cpu.ebx;
                    break;
                case 4:
                    op_src->val = cpu.esp;
                    break;
                case 5:
                    op_src->val = cpu.ebp;
                    break;
                case 6:
                    op_src->val = cpu.esi;
                    break;
                case 7:
                    op_src->val = cpu.edi;
                    break;
                default:
                    assert(0);
            }
            break;
            case OP_TYPE_IMM:
                break;
            case OP_TYPE_MEM:
                op_src->val = swaddr_read(op_src->addr, DATA_BYTE);
                break;
            default:
                assert(0);
    }
    //提取第二参数
    switch (op_dest->type){
        case OP_TYPE_REG:
            switch (op_dest->reg){
                case 0:
                    op_dest->val = cpu.eax;
                    break;
                case 1:
                    op_dest->val = cpu.ecx;
                    break;
                case 2:
                    op_dest->val = cpu.edx;
                    break;
                case 3:
                    op_dest->val = cpu.ebx;
                    break;
                case 4:
                    op_dest->val = cpu.esp;
                    break;
                case 5:
                    op_dest->val = cpu.ebp;
                    break;
                case 6:
                    op_dest->val = cpu.esi;
                    break;
                case 7:
                    op_dest->val = cpu.edi;
                    break;
                default:
                    assert(0);
            }
            break;
        case OP_TYPE_MEM:
            op_dest->val = swaddr_read(op_dest->addr, DATA_BYTE);
            break;
        default:

            assert(0);
    }
    //进行减法运算
    int result = op_dest->val - op_src->val;
    //更新标志寄存器
    cpu.eflags.CF = op_dest->val < op_src->val;
    cpu.eflags.ZF = result == 0;
    cpu.eflags.SF = result < 0;
    cpu.eflags.OF = (MSB(op_dest->val) != MSB(op_src->val)) && (MSB(op_dest->val) != MSB(result));
    //返回指令长度
    return len + 1;
    

}

#include "cpu/exec/template-end.h"



